#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <unordered_map>
#include "TcpServer.hpp"
#include "HttpProtocol.hpp"

class HttpServer;
using namespace TcpServerModule;
using http_handler_t = std::function<void(HttpRequest&, HttpResponse&, HttpServer&)>;

class HttpServer 
{
public:
    HttpServer(int port)
        :_tsvr(std::make_unique<TcpServer>(port))
        , _session_manager(std::make_unique<SessionManager>())
    {}

    void Register(std::string funcname, http_handler_t func)
    {
        _route[funcname] = func;
    }

    bool SafeCheck(const std::string &service)
    {
        auto iter = _route.find(service);
        return iter != _route.end();
    }

    void Start()
    {
        _tsvr->InitServer([this](SockPtr sockfd, InetAddr client)
        {
            return HandleRequest(sockfd, client);
        });
        _tsvr->Loop();
    }

    std::string AddSession(session_ptr s)
    {
        return _session_manager->AddSession(s);
    }

    std::string DebugPrint()
    {
        return _session_manager->DebugPrint();
    }

    void IsHasSession(HttpRequest &req)
    {
        std::string sessionid = req.SessionId();
        LOG(LogLevel::DEBUG) << "cookie: " << sessionid;
        if(!sessionid.empty())
        {
            session_ptr s = _session_manager->GetSession(sessionid);
            if(s != nullptr)
                LOG(LogLevel::DEBUG) << s->UserName() << "正在活跃中...";
            else
                LOG(LogLevel::DEBUG) << "cookie: " << sessionid << " 已过期，需要清理！";
        }
    }

    bool HandleRequest(SockPtr sockfd, InetAddr client)
    {
        LOG(LogLevel::DEBUG) << "get a new client: " << sockfd->Fd() << " addr info: " << client.Addr();
        
        // 1.接收请求报文
        std::string http_request;
        sockfd->Recv(&http_request); // 暂时不做报文完整性的处理

        // 2.请求报文反序列化
        HttpResponse resp;
        HttpRequest req;
        req.Deserialize(http_request);
        //req.Print();
        //请求应该分为两类：1.请求一般的静态资源 2.提交参数，携带参数，需要我们进行交互设定
        if(req.IsHasArgs())
        {
            std::string service = req.Path();
            if(SafeCheck(service))
            {
                _route[service](req, resp, *this);   // login
                LOG(LogLevel::DEBUG) << DebugPrint();
            }   
            else
            {
                IsHasSession(req); 
                resp.Bulid(req); // debug
                LOG(LogLevel::DEBUG) << DebugPrint();

            }
        }
        else
        {
            // 3.完善应答结构体的字段
            IsHasSession(req); 
            resp.Bulid(req);
            LOG(LogLevel::DEBUG) << DebugPrint();

        }

        // 4.应答报文序列化
        std::string resp_str;
        resp.Serialize(&resp_str);

        // 5.应答报文发送
        sockfd->Send(resp_str);
        
        //std::cout << http_request << std::endl; //字节流请求
        // 读取请求，对请求进行分析处理 --> 文本处理！
        // 1.读取请求的完整性 --- 暂时不做
        // 2.完整http反序列化，http response序列化...
        // demo 1: 直接返回一个固定内容
        // std::string httpresponse;
        // Demo1(&httpresponse);
        //sockfd->Send(Demo1());

        return true;
    }

    ~HttpServer(){}
private:
    std::string Demo1()
    {
        std::string status_line = "HTTP/1.1 200 OK" + Sep + BlankLine;

        // std::string body = "<!DOCTYPE html>\
        //                    <html>\
        //                    <head>\
        //                    <meta charset= \"UTF-8\">\
        //                    <title> 星际和平公司战略投资部</title>\
        //                    </head>\
        //                    <body>\
        //                    <h1> 星际和平公司战略投资部</h1>\
        //                    <h1> 该网站在努力创建，请勿着急！</h1>\
        //                    </body> </html>";

        std::string body = "<!DOCTYPE html>\
                           <html>\
                           <head>\
                           <meta charset= \"UTF-8\">\
                           <title> Helloworld </title>\
                           </head>\
                           <body>\
                           <h1> Helloworld </h1>\
                           </body> </html>";
        return status_line + body;
    }
private:
    std::unique_ptr<TcpServer> _tsvr;
    std::unordered_map<std::string, http_handler_t> _route; // 功能路由
    std::unique_ptr<SessionManager> _session_manager; // 会话管理器
   
};